home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / prog_gen / wdj0796.zip / CC.ZIP / CC.C next >
C/C++ Source or Header  |  1994-02-02  |  43KB  |  1,300 lines

  1. /*  Note:  this source code is really crappy, but it was written in
  2.  *  a big hurry.
  3.  */
  4.  
  5. /* SS != DS if DLL, fix for bcc and ztc */
  6. /* disabling smart callbacks for bcc and ztc */
  7.  
  8. /*
  9.  *  cc - Vendor-independent interface to C compilers.
  10.  *  
  11.  *  to build me, type "cc -dos -wild cc.c".
  12.  */
  13.  
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <stdarg.h>
  17. #include <errno.h>
  18. #include <stdio.h>
  19.  
  20. #include <process.h>
  21. #include <dos.h>
  22.  
  23. int     Version = 0x0009;
  24.  
  25. #if defined(__BORLANDC__)
  26.     #include <io.h>
  27.     #include <fcntl.h>
  28.     #include <sys\stat.h>
  29.     #define WRITE   write
  30.     #define OPEN    open
  31.     #define CLOSE   close
  32.     #define UNLINK  unlink
  33.     #define STRICMP stricmp
  34.     #define CREAT   creat
  35. #elif defined(__ZTC__)
  36.     #include <io.h>
  37.     #define WRITE   write
  38.     int _okbigbuf = 0;  /* makes more memory available */
  39.     #define STRICMP strcmpl
  40.     #define spawnvp(a,b,c) spawnvp(a,b,(const char * const *)c)
  41.     #define execvp(b,c) execvp(b,(const char * const *)c)
  42. #elif defined(_MSC_VER)
  43.     #include <io.h>
  44. /*    #include <sys\stat.h> */
  45. /*    #include <fcntl.h> */
  46.     #define OPEN    open
  47.     #define CLOSE   close
  48.     #define UNLINK  unlink
  49.     #define CREAT   creat
  50.     #define WRITE   _write
  51.     #define STRICMP _stricmp
  52. #endif
  53.  
  54.  
  55. #define TRUE    1
  56. #define FALSE   0
  57.  
  58. const char *Extensions = "c\0cpp\0res\0rc\0def\0obj\0lib\0lib0\0lib1\0\0";
  59. enum { EXT_C=0, EXT_CPP, EXT_RES, EXT_RC, EXT_DEF, EXT_OBJ,
  60.        EXT_LIB, EXT_LIB0, EXT_LIB1, N_EXT };
  61.  
  62. typedef struct  COMPILE_OPTIONS
  63.     {
  64.     int     ProcessorType;  /* 0=8088, 1=80186, etc. */
  65.     int     Align;          /* 1=byte align, 2=word align, etc. */
  66.     int     CompileOnly;    /* TRUE if compile only, no link */
  67.     char    MemoryModel;    /* 't' = tiny, 's' = small, etc. */
  68.     int     SsNeqDs;        /* TRUE if should assume SS != DS */
  69.     int     Windows;        /* TRUE = Windows, FALSE = DOS */
  70.     int     Dll;            /* TRUE = make .dll */
  71.     int     Com;            /* TRUE = make .com (for DOS) */
  72.     int     Debug;          /* 0=no debug, 1=line numbers, 2=all */
  73.     int     StackCheck;     /* TRUE=compile stack checks in */
  74.     int     CPlusPlus;      /* TRUE if using C++ instead of C */
  75.     char    *RunName;       /* Name to use for executable file */
  76.     int     Windows30;      /* TRUE if mark exe/dll for Windows 3.0 */
  77.     int     MapFile;        /* TRUE if we should generate map file */
  78.     int     Verbose;        /* TRUE if we are verbose!  */
  79.     int     WildCards;      /* TRUE if command-line should handle wild-cards */
  80.     char    Prologue;       /* 'a' = AX, 's' = SS, 'd' = DGROUP, '\0' = default */
  81.     int     NoSmart;        /* TRUE if user wants no smart callbacks */
  82.     char   *CodeSegment;    /* name of code segment */
  83.     int     Optimize;       /* zero means no optimize */
  84.     char   *LibName;        /* name of library to update */
  85.     int     Strict;         /* =1  -> user did -DSTRICT
  86.                                =0  -> user did nothing
  87.                                =-1 -> user did -D        */
  88.     }           COMPILE_OPTIONS;
  89.  
  90. enum    COMPILER_TYPE    { MSC, BCC, SC };
  91. typedef void    (*COMPILER_FUNC) (enum COMPILER_TYPE , COMPILE_OPTIONS *);
  92. typedef struct  COMPILER
  93.     {
  94.     char            *CompilerName;
  95.     enum COMPILER_TYPE CompilerType;
  96.     COMPILER_FUNC   CompilerFunc;
  97.     }           COMPILER;
  98.  
  99. void    Msc(enum COMPILER_TYPE, COMPILE_OPTIONS *);
  100. void    Bcc(enum COMPILER_TYPE, COMPILE_OPTIONS *);
  101. void    Ztc(enum COMPILER_TYPE, COMPILE_OPTIONS *);
  102.  
  103. COMPILER    Compilers[] =
  104.     {
  105.         { "msc", MSC, Msc },
  106.         { "bcc", BCC, Bcc },
  107.         { "sc",  SC,  Ztc },
  108.     };
  109. #define     NCOMPILERS  (sizeof(Compilers) / sizeof(COMPILER))
  110.  
  111. #define MAX_FILES   128
  112.  
  113. #define MAX_MACROS   128
  114. int     NMacros;
  115. char    *Macros[MAX_MACROS];
  116.  
  117.  
  118. char    *DefName;
  119. char    CommandLine[128];
  120.  
  121. char    *UsageMessage   =
  122. "cc - Vendor-independent C/C++ Compilation (Windows/DOS Developer's Journal)\0"
  123. "Usage: cc [options] sourcefiles\0"
  124. "\0"
  125. "-1   use 80186 instructions\0"
  126. "-2   use 80286 instructions\0"
  127. "-3   use 80386 instructions\0"
  128. "-4   use 80486 instructions\0"
  129. "-30  mark exe/dll 3.0 compatible\0"
  130. "-a{1|2}  byte or word alignment\0"
  131. "     (default is byte alignment)\0"
  132. "-c   compile only, no link\0"
  133. "-com create .com (DOS only)\0"
  134. "-C   disable smart callbacks\0"
  135. "-d   include complete debug info\0"
  136. "-dl  include line numbers only\0"
  137. "-Dname{=def}  define macro\0"
  138. "-dos compile/link for DOS\0"
  139. "-mx{!}  specify memory model:\0"
  140. "    t = tiny    s = small\0"
  141. "    c = compact m = medium\0"
  142. "    l = large   h = huge\0"
  143. "    ! means assume DS != SS\0"
  144. "      (the default for .dll)\0"
  145. "-M   don't generate map file\0"
  146. "-NT<name>  set name of code segment\0"
  147. "-o<name> set name of target executable\0"
  148. "     name must end in .com, .exe, or .dll\0"
  149. "-O   optimize generated code\0"
  150. "-p   use C++ compiler\0"
  151. "-s   enable stack checks\0"
  152. "-u<libname> Update library with .obj files\0"
  153. "-v   Verbose (don't delete .rsp files)\0"
  154. "-w{e|d}{a|s|d}\0"
  155. "    |    |  (.exe default is SS)\0"
  156. "    |    |  (.dll default is DGROUP)\0"
  157. "    |    +-> a=AX, s=SS, d=DGROUP\0"
  158. "    +-> e=.exe (default), d=.dll\0"
  159. "    default is -we (Windows .exe, use SS)\0"
  160. "-wild link with special wildcard .obj\0"
  161. "\0"
  162. ;
  163.  
  164. #define MAX_ARGS    (64)
  165. int     NCmdArgs    = 1;
  166. char    *CmdArgs[MAX_ARGS];
  167.  
  168.  
  169. #include "common.c"
  170.  
  171. FileType    FilesByExt[N_EXT];
  172.  
  173. FILE    *OpenFile(const char *FileName, const char *Mode)
  174.     {
  175.     FILE    *File;
  176.  
  177.     File    = fopen(FileName, Mode);
  178.     if(File == NULL)
  179.         {
  180.         fprintf(stderr, "Can't open '%s' for %s.\n", FileName,
  181.             (*Mode == 'w') ? "writing" : "reading");
  182.         exit(EXIT_FAILURE);
  183.         }
  184.     return  File;
  185.     }
  186.  
  187. /* GetCompiler() return which vendor's compiler to use. */
  188. COMPILER *GetCompiler(void)
  189.     {
  190.     char    Buffer[64];
  191.     char    *CC;
  192.     int     i;
  193.  
  194.     CC      = getenv("CC");
  195.     if(CC && *CC)
  196.         {
  197.         char    *Output = Buffer;
  198.  
  199.         while(*CC != ' ' && *CC != '\0')
  200.             *Output++   = *CC++ | ' ';    /* lowercase it */
  201.         *Output = '\0';
  202.         while(*CC == ' ')
  203.             ++CC;
  204.         if(*CC)
  205.             CmdArgs[NCmdArgs++]  = CC;
  206.  
  207.         for(i = 0; i < NCOMPILERS; ++i)
  208.             if(!strcmp(Buffer, Compilers[i].CompilerName))
  209.                 return &Compilers[i];
  210.         fprintf(stderr, "'%s': I do not recognize this compiler name "
  211.             "(defined in your\n"
  212.             "   'CC' environment variable. The names I recognize are:\n"
  213.             "    ",
  214.             getenv("CC"));
  215.  
  216.         for(i = 0; i < NCOMPILERS; ++i)
  217.             {
  218.             fprintf(stderr, "'%s'", Compilers[i].CompilerName);
  219.             if(i == (NCOMPILERS-2))
  220.                 fprintf(stderr, " and ");
  221.             else if(i < (NCOMPILERS-1))
  222.                 fprintf(stderr, ", ");
  223.             }
  224.         fprintf(stderr, "\n");
  225.         }
  226.     return 0;
  227.     }
  228.  
  229. void    Usage(void)
  230.     {
  231.     int     NLines;
  232.     char    *Line1, *Line2;
  233.  
  234.     Line1   = UsageMessage;
  235.     while(strlen(Line1))    /* blank line signals start of two-column */
  236.         {
  237.         fprintf(stderr, "%s\n", Line1);
  238.         Line1   += strlen(Line1)+1;
  239.         }
  240.     Line2   = ++Line1;
  241.     for(NLines = 0; strlen(Line2); ++NLines)
  242.         Line2   += strlen(Line2)+1;
  243.     Line2   = Line1;
  244.     NLines /= 2;
  245.     while(NLines-- > 0) /* Count total # of option lines */
  246.         Line2   += strlen(Line2)+1;
  247.     do  {
  248.         int     Column;
  249.  
  250.         
  251.         fprintf(stderr, "  %s", Line1);
  252.         for(Column = strlen(Line1); Column < 36; ++Column)
  253.             fprintf(stderr, " ");
  254.         fprintf(stderr, "%s\n", Line2);
  255.         Line1   += strlen(Line1)+1;
  256.         if(*Line2)
  257.             Line2   += strlen(Line2)+1;
  258.         }   while(*Line2);
  259.     exit(EXIT_FAILURE);
  260.     }
  261.  
  262. void    ErrorOption(char *Arg)
  263.     {
  264.     ErrorOutput("'");
  265.     ErrorOutput(Arg);
  266.     ErrorOutput("': Unknown option\r\n");
  267.     }
  268.  
  269. int DoOption(char *OriginalArg, COMPILE_OPTIONS *Options)
  270.     {
  271.     char    ModelChar = '\0';
  272.     char    OptionChar;
  273.     char    *Arg;
  274.  
  275.     Arg = OriginalArg + 1;  /* skip leading '-' or '/' */
  276.     OptionChar = *Arg++;
  277.  
  278.     switch(OptionChar)
  279.         {
  280.         case    '3' :
  281.             if(!strcmp(Arg, "0"))   /* if option was "-30" */
  282.                 {
  283.                 Options->Windows30  = TRUE;
  284.                 break;
  285.                 }
  286.         case    '0' :
  287.         case    '1' :
  288.         case    '2' :
  289.         case    '4' :
  290.             Options->ProcessorType   = OptionChar - '0';
  291.             if(*Arg)
  292.                 ErrorOption(OriginalArg);
  293.             break;
  294.         case    'a' :
  295.             if(Arg[1] == '\0' &&
  296.                 (*Arg == '1' || *Arg == '2'))
  297.                 Options->Align  = *Arg - '0';
  298.             else
  299.                 ErrorOption(OriginalArg);
  300.             break;
  301.         case    'c' :
  302.             if(*Arg == '\0')
  303.                 Options->CompileOnly    = TRUE;
  304.             else if(!strcmp(OriginalArg, "-com"))
  305.                 {
  306.                 if(ModelChar && ModelChar != 't')
  307.                     ErrorOutput("Only tiny memory model is compatible with .com file\r\n");
  308.                 else
  309.                     {
  310.                     Options->MemoryModel    = 't';
  311.                     Options->Com            = TRUE;
  312.                     }
  313.                 }
  314.             else
  315.                 ErrorOption(OriginalArg);
  316.             break;
  317.         case    'C' :
  318.             if(*Arg == '\0')
  319.                 Options->NoSmart    = TRUE;
  320.             else
  321.                 ErrorOption(OriginalArg);
  322.             break;
  323.         case    'd' :   /* include debugging information */
  324.             if(*Arg == '\0')
  325.                 Options->Debug  = 2;
  326.             else if(!strcmp(OriginalArg, "-dl"))
  327.                 Options->Debug  = 1;
  328.             else if(!strcmp(OriginalArg, "-dos"))
  329.                 Options->Windows    = FALSE;
  330.             else
  331.                 ErrorOption(OriginalArg);
  332.             break;
  333.         case    'D' :
  334.             if(!strcmp(OriginalArg, "-DSTRICT"))
  335.                 Options->Strict = 1;
  336.             else if(*Arg == '\0')
  337.                 Options->Strict = -1;
  338.             Macros[NMacros++]   = OriginalArg;
  339.             break;
  340.         case    'M' :
  341.             Options->MapFile    = FALSE;
  342.             break;
  343.         case    'm' :
  344.             switch(ModelChar = OptionChar = *Arg++)
  345.                 {
  346.                 case    's' :
  347.                 case    'm' :
  348.                 case    'l' :
  349.                 case    'h' :
  350.                     if(Options->Com)
  351.                         {
  352.                         ErrorOutput("You must use the tiny memory model to get a .com file\r\n");
  353.                         OptionChar  = 't';
  354.                         }
  355.                 case    't' :
  356.                     if(ModelChar == 't')
  357.                         {
  358.                         Options->Com            = TRUE;
  359.                         Options->Windows        = FALSE;
  360.                         }
  361.                     Options->MemoryModel    = OptionChar;
  362.                     OptionChar              = *Arg++;
  363.                     if(OptionChar)
  364.                         {
  365.                         if(OptionChar == '!')
  366.                             Options->SsNeqDs    = TRUE;
  367.                         else
  368.                             ErrorOption(OriginalArg);
  369.                         }
  370.                     break;
  371.                 default :
  372.                     ErrorOption(OriginalArg);
  373.                 }
  374.             break;
  375.         case    'N' :
  376.             if(*Arg == 'T')
  377.                 Options->CodeSegment    = Arg+1;
  378.             else
  379.                 ErrorOption(OriginalArg);
  380.             break;
  381.         case    'o' :   /* specify executable filename */
  382.             if(!*Arg)
  383.                 ErrorOption(OriginalArg);
  384.             else
  385.                 {
  386.                 char    *Ext    = FindExtension(Arg);
  387.  
  388.                 Options->RunName = Arg;
  389.                 if(!STRICMP(Ext, "com"))
  390.                     Options->Com    = TRUE;
  391.                 else if(!STRICMP(Ext, "dll"))
  392.                     Options->Dll    = Options->Windows  = TRUE;
  393.                 if(*Ext)
  394.                     *--Ext  = '\0';
  395.                 }
  396.             break;
  397.         case    'O' :
  398.             if(*Arg)
  399.                 ErrorOption(OriginalArg);
  400.             else
  401.                 Options->Optimize   = TRUE;
  402.             break;
  403.         case    'p' :   /* use C++ compiler */
  404.             if(*Arg)
  405.                 ErrorOption(OriginalArg);
  406.             else
  407.                 Options->CPlusPlus = TRUE;
  408.             break;
  409.         case    's' :   /* enable stack checks */
  410.             if(*Arg)
  411.                 ErrorOption(OriginalArg);
  412.             else
  413.                 Options->StackCheck = TRUE;
  414.             break;
  415.         case    'u' :   /* update library */
  416.             if(*Arg)
  417.                 Options->LibName    = Arg;
  418.             else
  419.                 ErrorOption(OriginalArg);
  420.             break;
  421.         case    'v' :   /* be verbose # */
  422.             fprintf(stderr, "cc v%d.%d\n", Version>>8, Version&0x0FF);
  423.             Options->Verbose        = TRUE;
  424.             break;
  425.         case    'w' :   /* compile for Windows */
  426.             if(*Arg == '\0' || !strcmp(OriginalArg, "-we"))
  427.                 {
  428.                 Options->Prologue   = 's';
  429.                 Options->Windows    = TRUE;
  430.                 }
  431.             else if(!strcmp(OriginalArg, "-wd"))
  432.                 {
  433.                 Options->Prologue   = 'd';
  434.         Options->Windows    = TRUE;
  435.                 Options->Dll        = TRUE;
  436.                 Options->SsNeqDs    = TRUE;
  437.                 }
  438.             else if(strchr("ed", OriginalArg[2])
  439.                 &&  strchr("ads", OriginalArg[3])
  440.                 &&  OriginalArg[4] == '\0')
  441.                 {
  442.                 Options->Windows    = TRUE;
  443.                 if(OriginalArg[2] == 'd')
  444.                     {
  445.                     Options->Dll        = TRUE;
  446.                     Options->SsNeqDs    = TRUE;
  447.                     }
  448.                 Options->Prologue   = OriginalArg[3];
  449.                 }
  450.             else if(!strcmp(OriginalArg, "-wild"))
  451.                 Options->WildCards  = TRUE;
  452.             else
  453.                 ErrorOption(OriginalArg);
  454.             break;
  455.         default :
  456.             ErrorOption(OriginalArg);
  457.         }
  458.     return ErrorCount == 0;
  459.     }
  460.  
  461.  
  462. int     main(int argc, char **argv)
  463.     {
  464.     static    COMPILE_OPTIONS CompileOptions =
  465.         {
  466.         0,      /* processor type = 8088 */
  467.         1,      /* byte alignment */
  468.         FALSE,  /* compile and link */
  469.         's',    /* assume small memory model */
  470.         FALSE,  /* do not assume SS != DS */
  471.         TRUE,   /* Assume Windows executable, not DOS */
  472.         FALSE,  /* assume .exe, not .dll */
  473.         FALSE,  /* assume .exe, not .com */
  474.         FALSE,  /* assume no debugging information */
  475.         FALSE,  /* assume no stack checking */
  476.         FALSE,  /* assume C, not C++ */
  477.         NULL,   /* don't know runname yet */
  478.         FALSE,  /* assume Windows 3.1, not Windows 3.0 */
  479.         TRUE,   /* do generate map file */
  480.         FALSE,  /* don't be verbose */
  481.         FALSE,  /* don't handle wildcards */
  482.         '\0',   /* don't assume anything about prologue code */
  483.         0,      /* assume smart callbacks */
  484.         NULL,   /* default code segment name */
  485.         0,      /* no optimization */
  486.         NULL,   /* No library to update */
  487.         FALSE,  /* user has not said -DSTRICT */
  488.         };
  489.     int         i, j;
  490.     COMPILER    *Compiler;
  491.  
  492.     if(argc < 2)
  493.         Usage();
  494.     Compiler    = GetCompiler();
  495.     if(!Compiler)
  496.         {
  497.         ErrorOutput("Please set your CC environment variable "
  498.             "to the name\r\nof the compiler you wish to use,\r\n"
  499.              "Microsoft = 'msc', Borland = 'bcc', Symantec = 'sc'\r\n"
  500.              "(Zortech support abandoned!)\r\n");
  501.         exit(EXIT_FAILURE);
  502.         }
  503.  
  504.     for(i = 1; i < argc; ++i)
  505.         if(*argv[i] == '-' || *argv[i] == '/')
  506.             DoOption(argv[i], &CompileOptions);
  507.         else
  508.             break;
  509.  
  510.     if(CompileOptions.Windows && CompileOptions.Strict == 0)
  511.         Macros[NMacros++]   = "-DSTRICT";
  512.     if(ErrorCount > 0)
  513.         {
  514.         Usage();
  515.         exit(EXIT_FAILURE);
  516.         }
  517.     if(CompileOptions.Windows && !CompileOptions.Prologue)
  518.         CompileOptions.Prologue = CompileOptions.Dll ? 'd' : 's';
  519.  
  520.     for(j=i; j < argc; ++j)
  521.         {
  522.         char    *Ext    = FindExtension(argv[j]);
  523.  
  524.         if(!Ext || !*Ext || !STRICMP(Ext, "c")
  525.             || !STRICMP(Ext, "obj") || !STRICMP(Ext, "cpp"))
  526.             {
  527.             if(!CompileOptions.RunName)
  528.                 {
  529.                 static  char    RunName[128];
  530.                 CopyFileName(argv[j], RunName);
  531.                 CompileOptions.RunName  = RunName;
  532.                 }
  533.             }
  534.         }
  535.     SortFiles(argv+i, FilesByExt, Extensions, "c");
  536. #if 0
  537. {
  538. int i, j;
  539. for(i = 0; i < 7; ++i)
  540.     {
  541.     fprintf(stderr, "[%d] '.%-3.3s' %d files\n", i,
  542.         FilesByExt[i].Extension, FilesByExt[i].NFiles);
  543.     for(j = 0; j < FilesByExt[i].NFiles; ++j)
  544.         fprintf(stderr, "    '%s'\n", FilesByExt[i].Array[j]);
  545.     }
  546. }
  547. #endif
  548.  
  549.     if(     FilesByExt[EXT_C  ].NFiles == 0
  550.         &&  FilesByExt[EXT_CPP].NFiles == 0
  551.         &&  FilesByExt[EXT_OBJ].NFiles == 0
  552.       )
  553.         {
  554.         fprintf(stderr, "You must supply at least one source or object file\n");
  555.         exit(EXIT_FAILURE);
  556.         }
  557.     if(     FilesByExt[EXT_RC  ].NFiles +
  558.             FilesByExt[EXT_RES].NFiles > 1
  559.       )
  560.         {
  561.         fprintf(stderr, "You can only specify one .rc or .res file.\n");
  562.         exit(EXIT_FAILURE);
  563.         }
  564.  
  565.     for(i = 0; i < NMacros; ++i)
  566.         CmdArgs[NCmdArgs++] = Macros[i];
  567.  
  568.     if(ErrorCount == 0)
  569.         Compiler->CompilerFunc(Compiler->CompilerType, &CompileOptions);
  570.     return EXIT_SUCCESS;
  571.     }
  572.  
  573. void    CompileRc(enum COMPILER_TYPE Compiler, COMPILE_OPTIONS *Options)
  574.     {
  575.     int     Status;
  576.     char    RcFileName[128];
  577.     char   *RC = (Compiler == BCC ? "brc" : "rc");
  578.  
  579.     strcpy(RcFileName, "");
  580.     if(FilesByExt[EXT_RC].NFiles > 0)
  581.         strcpy(RcFileName, FilesByExt[EXT_RC].Array[0]);
  582.     else if(FilesByExt[EXT_RES].NFiles <= 0)
  583.         {
  584.         FILE    *RcFile;
  585.         strcpy(RcFileName, Options->RunName);
  586.         strcat(RcFileName, ".rc");
  587.         RcFile  = fopen(RcFileName, "r");
  588.         if(RcFile != NULL)
  589.             fclose(RcFile);
  590.         else
  591.             strcpy(RcFileName, "");
  592.         }
  593.     if(RcFileName[0])
  594.         {
  595.         memset(CmdArgs, 0, MAX_ARGS * sizeof(char *));
  596.         CmdArgs[0]  = RC;
  597.         NCmdArgs    = 1;
  598.         CmdArgs[NCmdArgs++] = "-r";
  599.         CmdArgs[NCmdArgs++] = RcFileName;
  600.         EchoArgs(CmdArgs, NCmdArgs);
  601.         Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  602.         if(Status)
  603.             exit(EXIT_FAILURE);
  604.         }
  605.     memset(CmdArgs, 0, MAX_ARGS * sizeof(char *));
  606.     CmdArgs[0]  = RC;
  607.     NCmdArgs    = 1;
  608.     if(RcFileName[0])
  609.         {
  610.         *FindExtension(RcFileName)  = '\0';
  611.         strcat(RcFileName, "res");
  612.         }
  613.     else
  614.         if(FilesByExt[EXT_RES].NFiles > 0)
  615.             strcpy(RcFileName, FilesByExt[EXT_RES].Array[0]);
  616.         else
  617.             {
  618.             FILE    *RcFile;
  619.             strcpy(RcFileName, Options->RunName);
  620.             strcat(RcFileName, ".res");
  621.             RcFile  = fopen(RcFileName, "r");
  622.             if(RcFile != NULL)
  623.                 fclose(RcFile);
  624.             else
  625.                 strcpy(RcFileName, "");
  626.             }
  627.     if(RcFileName[0])
  628.         {
  629.         char    Target[128];
  630.         memset(CmdArgs, 0, MAX_ARGS * sizeof(char *));
  631.         CmdArgs[0]  = RC;
  632.         NCmdArgs    = 1;
  633.         if(Options->Windows30)
  634.             CmdArgs[NCmdArgs++] = "-30";
  635.         CmdArgs[NCmdArgs++] = RcFileName;
  636.         strcpy(Target, Options->RunName);
  637.         strcat(Target, Options->Dll ? ".dll" : ".exe");
  638.         CmdArgs[NCmdArgs++] = Target;
  639.         EchoArgs(CmdArgs, NCmdArgs);
  640.         Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  641.         if(Status)
  642.             exit(EXIT_FAILURE);
  643.         }
  644.     if(Options->Dll)
  645.         {
  646.         char    Dll[128];
  647.         char    Lib[128];
  648.         strcpy(Dll, Options->RunName);
  649.         strcat(Dll, ".dll");
  650.         strcpy(Lib, Options->RunName);
  651.         strcat(Lib, ".lib");
  652.  
  653.         memset(CmdArgs, 0, MAX_ARGS * sizeof(char *));
  654.         CmdArgs[0]  = "implib";
  655.         NCmdArgs    = 1;
  656.         CmdArgs[NCmdArgs++] = Lib;
  657.         CmdArgs[NCmdArgs++] = Dll;
  658.         EchoArgs(CmdArgs, NCmdArgs);
  659.         Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  660.         if(Status)
  661.             exit(EXIT_FAILURE);
  662.         }
  663.     }
  664.  
  665.  
  666. void    Msc(enum COMPILER_TYPE Compiler, COMPILE_OPTIONS *Options)
  667.     {
  668.     int     Status;
  669.     FILE    *ResponseFile;
  670.  
  671.     if(FilesByExt[EXT_C].NFiles == 0 && FilesByExt[EXT_CPP].NFiles == 0)
  672.         goto    LINK;
  673.     ResponseFile    = OpenFile("wddjcc.rsp", "w");
  674.  
  675.     CmdArgs[0] = "cl";
  676.  
  677. //    CmdArgs[NCmdArgs++] = "/c /f-";
  678.     CmdArgs[NCmdArgs++] = "/c ";
  679.     if(!Options->Verbose)
  680.         CmdArgs[NCmdArgs++] = "/nologo";
  681.     CmdArgs[NCmdArgs++] = "/W3";
  682.     if(Options->Debug >= 2)
  683.         CmdArgs[NCmdArgs++] = "/Zdie";
  684.     else if(Options->Debug >= 1)
  685.         CmdArgs[NCmdArgs++] = "/Zd";
  686.     if(Options->CPlusPlus)
  687.         CmdArgs[NCmdArgs++] = "/vmg";
  688.         //otherwise, can't declare pointer to mem func before class
  689.  
  690.     if(Options->Optimize)
  691.         CmdArgs[NCmdArgs++] = "/Ox";
  692.     if(Options->Align == 1)
  693.         CmdArgs[NCmdArgs++] = "/Zp";
  694.     if(Options->CodeSegment && *Options->CodeSegment)
  695.         {
  696.         static char CodeSegment[64];
  697.         sprintf(CodeSegment, "/NT%s", Options->CodeSegment);
  698.         CmdArgs[NCmdArgs++] = CodeSegment;
  699.         }
  700.  
  701. /* >>> begin /G options */
  702.     {
  703.     static
  704.     char    GOption[10];
  705.     char    *Output = GOption;
  706.     int     OptionOut;
  707.  
  708.     OptionOut   = FALSE;
  709.     if(Options->ProcessorType >= 1)
  710.         {
  711.         strcpy(Output, "/G"), Output += 2, OptionOut = TRUE;
  712.         *Output++   = Options->ProcessorType + '0';
  713.         }
  714.     if(Options->Windows)
  715.         {
  716.         if(!OptionOut)
  717.             strcpy(Output, "/G"), Output += 2, OptionOut = TRUE;
  718.         if(Options->NoSmart)
  719.             *Output++   = 'w';
  720.         else
  721.             *Output++   = Options->Dll ? 'D' : 'A';
  722.         }
  723.     if(!Options->StackCheck)
  724.         {
  725.         if(!OptionOut)
  726.             strcpy(Output, "/G"), Output += 2, OptionOut = TRUE;
  727.         *Output++   = 's';
  728.         }
  729.     if(OptionOut)
  730.         {
  731.         *Output++   = '\0';
  732.         CmdArgs[NCmdArgs++] = GOption;
  733.         }
  734.     }
  735. /* <<< end /G options */
  736.  
  737.     if(Options->Windows && !Options->NoSmart)
  738.         {
  739.         static  char Prologue[7];
  740.         sprintf(Prologue, "/GE%cme", Options->Prologue);
  741.         CmdArgs[NCmdArgs++] = Prologue;
  742.         }
  743.  
  744.  
  745.         {
  746.         static
  747.         char    AOption[5];
  748.         char    *Output = AOption;
  749.     
  750.         strcpy(Output, "/A"), Output    += 2;
  751.         *Output++   = Options->MemoryModel ^ ' '; /* map to uppercase */
  752.         if(Options->Dll || Options->SsNeqDs)
  753.             *Output++   = 'w';      /* SS != DS */
  754.         *Output++   = '\0';
  755.         CmdArgs[NCmdArgs++] = AOption;
  756.         }
  757.  
  758.     {
  759.     int     i;
  760.     char    Path[128];
  761.     for(i = 0; i < FilesByExt[EXT_C].NFiles; ++i)
  762.         {
  763.         CopyPathName(FilesByExt[EXT_C].Array[i], Path);
  764.         fprintf(ResponseFile, " %s%s.c", Options->CPlusPlus
  765.             ? "/Tp" : "", Path);
  766.         }
  767.     for(i = 0; i < FilesByExt[EXT_CPP].NFiles; ++i)
  768.         {
  769.         CopyPathName(FilesByExt[EXT_CPP].Array[i], Path);
  770.         fprintf(ResponseFile, " %s.cpp", Path);
  771.         }
  772.     }
  773.     fclose(ResponseFile);
  774.     strcpy(CommandLine, "@wddjcc.rsp");
  775.     CmdArgs[NCmdArgs++] = CommandLine;
  776.     EchoArgs(CmdArgs, NCmdArgs);
  777.     Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  778.     if(!Options->Verbose)
  779.         unlink("@wddjcc.rsp");
  780.     if(Status)
  781.         exit(EXIT_FAILURE);
  782.     if(Options->CompileOnly)
  783.         return;
  784.     else
  785.         {
  786.         int     Status;
  787.         int     i;
  788.         char    Path[128];
  789.  
  790. LINK:
  791.         NCmdArgs    = 1;
  792.         memset(CmdArgs, 0, MAX_ARGS * sizeof(char *));
  793.         CmdArgs[0]  = "link";
  794.         ResponseFile    = OpenFile("wddjln.rsp", "w");
  795.         CmdArgs[NCmdArgs++] = "/nologo";
  796.         CmdArgs[NCmdArgs++] = "/NOE";
  797.         if(Options->Windows)
  798.             {
  799.             CmdArgs[NCmdArgs++] = "/align:16";
  800.             CmdArgs[NCmdArgs++] = "/NOD";
  801.             }
  802.         if(Options->MapFile)
  803.             CmdArgs[NCmdArgs++] = "/MAP:FULL /LINE";
  804.         if(Options->Debug > 0)
  805.             CmdArgs[NCmdArgs++] = "/CO";
  806.  
  807.         for(i = 0; i < FilesByExt[EXT_C].NFiles; ++i)
  808.             {
  809.             CopyPathName(FilesByExt[EXT_C].Array[i], Path);
  810.             fprintf(ResponseFile, " %s.obj", Path);
  811.             }
  812.         for(i = 0; i < FilesByExt[EXT_CPP].NFiles; ++i)
  813.             {
  814.             CopyPathName(FilesByExt[EXT_CPP].Array[i], Path);
  815.             fprintf(ResponseFile, " %s.obj", Path);
  816.             }
  817.         for(i = 0; i < FilesByExt[EXT_OBJ].NFiles; ++i)
  818.             {
  819.             CopyPathName(FilesByExt[EXT_OBJ].Array[i], Path);
  820.             fprintf(ResponseFile, " %s.obj", Path);
  821.             }
  822.         if(Options->WildCards)
  823.             fprintf(ResponseFile, " setargv.obj");
  824.         fprintf(ResponseFile, ",\n");
  825.         fprintf(ResponseFile, "%s.%s", Options->RunName,
  826.             Options->Com ? "com" : Options->Dll ? "dll" : "exe");
  827.         fprintf(ResponseFile, ",\n");
  828.         fprintf(ResponseFile, "%s,\n",
  829.             Options->MapFile ? Options->RunName : "NUL.MAP");
  830.  
  831.         if(Options->Windows)
  832.             {
  833.             for(i = 0; i < FilesByExt[EXT_LIB0].NFiles; ++i)
  834.                 {
  835.                 CopyPathName(FilesByExt[EXT_LIB0].Array[i], Path);
  836.                 fprintf(ResponseFile, "%s.lib + ", Path);
  837.                 }
  838.             fprintf(ResponseFile, "%c%scew", Options->MemoryModel,
  839.                 Options->Dll ? "dll" : "lib");
  840.             for(i = 0; i < FilesByExt[EXT_LIB1].NFiles; ++i)
  841.                 {
  842.                 CopyPathName(FilesByExt[EXT_LIB1].Array[i], Path);
  843.                 fprintf(ResponseFile, " + %s.lib", Path);
  844.                 }
  845.             fprintf(ResponseFile, " + libw");
  846.             }
  847.         for(i = 0; i < FilesByExt[EXT_LIB].NFiles; ++i)
  848.             {
  849.             CopyPathName(FilesByExt[EXT_LIB].Array[i], Path);
  850.             fprintf(ResponseFile, " + %s.lib", Path);
  851.             }
  852.         fprintf(ResponseFile, ",\n");
  853.  
  854.         if(Options->Windows)
  855.             {
  856.             if(FilesByExt[EXT_DEF].NFiles)
  857.                 fprintf(ResponseFile, "%s\n", FilesByExt[EXT_DEF].Array[0]);
  858.             else
  859.                 {
  860.                 GenModDef(Options->RunName, Options->Dll);
  861.                 fprintf(ResponseFile, "%s.def\n", Options->RunName);
  862.                 }
  863.             }
  864.         fprintf(ResponseFile, ";\n");
  865.         fclose(ResponseFile);
  866.         CmdArgs[NCmdArgs++] = "@wddjln.rsp";
  867.         EchoArgs(CmdArgs, NCmdArgs);
  868.         Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  869.         if(!Options->Verbose)
  870.             unlink("@wddjln.rsp");
  871.         if(Status)
  872.             exit(EXIT_FAILURE);
  873.         if(Options->Windows)
  874.             CompileRc(Compiler, Options);
  875.         }
  876.     }
  877.  
  878. void    Bcc(enum COMPILER_TYPE Compiler, COMPILE_OPTIONS *Options)
  879.     {
  880.     int     Status;
  881.     FILE    *ResponseFile;
  882.     FILE    *ConfigFile;
  883.  
  884.     if(FilesByExt[EXT_C].NFiles == 0 && FilesByExt[EXT_CPP].NFiles == 0)
  885.         goto    LINK;
  886.     ResponseFile    = OpenFile("wddjcc.rsp", "w");
  887.  
  888.     CmdArgs[0]      = "bcc";
  889.  
  890.     ConfigFile  = OpenFile("wddjcc.cfg", "w");
  891.     
  892.     CmdArgs[NCmdArgs++] = "-c";
  893.     if(getenv("INCLUDE"))
  894.         fprintf(ConfigFile, "-I%s\n", getenv("INCLUDE"));
  895.     if(getenv("LIB"))
  896.         fprintf(ConfigFile, "-L%s\n", getenv("LIB"));
  897.     if(Options->ProcessorType >= 1)
  898.         fprintf(ConfigFile, " -%c", '0' + Options->ProcessorType);
  899.     if(Options->Optimize)
  900.         CmdArgs[NCmdArgs++] = "-Ox-a";
  901.     if(Options->Align >= 2)
  902.         CmdArgs[NCmdArgs++] = "-a";
  903.     {
  904.     static char ModelOption[5];
  905.     sprintf(ModelOption, "-m%c%s", Options->MemoryModel,
  906.         Options->SsNeqDs ? "!" : "");
  907.     CmdArgs[NCmdArgs++] = ModelOption;
  908.     }
  909.     if(Options->Windows)
  910.         {
  911.         char    *WindowOption;
  912.         if(Options->NoSmart)
  913.             WindowOption    = Options->Dll ? "-WD" : "-WE";
  914.         else
  915.         switch(Options->Prologue)
  916.             {
  917.             case    'a' :   /* load from AX */
  918.                 WindowOption    = "-WE";
  919.                 break;
  920.             case    'd' :   /* load from DGROUP */
  921.                 WindowOption    = "-WDE";
  922.                 break;
  923.             case    's' :   /* load from SS */
  924.                 WindowOption    = "-WS";
  925.                 break;
  926.             }
  927.         CmdArgs[NCmdArgs++] = WindowOption;
  928.         }
  929.     else if(Options->Com)
  930.         CmdArgs[NCmdArgs++] = "-tDc -lt";
  931.     if(Options->Debug > 1)
  932.         CmdArgs[NCmdArgs++] = "-v";
  933.     else if(Options->Debug > 0)
  934.         CmdArgs[NCmdArgs++] = "-y";
  935.     if(Options->StackCheck)
  936.         CmdArgs[NCmdArgs++] = "-N";
  937.     if(Options->CodeSegment && *Options->CodeSegment)
  938.         {
  939.         static char CodeSegment[64];
  940.         sprintf(CodeSegment, "-zC%s", Options->CodeSegment);
  941.         CmdArgs[NCmdArgs++] = CodeSegment;
  942.         }
  943.     if(Options->CPlusPlus)  /* if using C++ */
  944.         CmdArgs[NCmdArgs++] = "-P";
  945.  
  946.     {
  947.     int     i;
  948.     char    Path[128];
  949.     for(i = 0; i < FilesByExt[EXT_C].NFiles; ++i)
  950.         {
  951.         CopyPathName(FilesByExt[EXT_C].Array[i], Path);
  952.         fprintf(ResponseFile, " %s.c", Path);
  953.         }
  954.     for(i = 0; i < FilesByExt[EXT_CPP].NFiles; ++i)
  955.         {
  956.         CopyPathName(FilesByExt[EXT_CPP].Array[i], Path);
  957.         fprintf(ResponseFile, " %s.cpp", Path);
  958.         }
  959.     }
  960.     fclose(ResponseFile);
  961.     fclose(ConfigFile);
  962.     strcpy(CommandLine, "+wddjcc.cfg");
  963.     strcat(CommandLine, " @wddjcc.rsp");
  964.     CmdArgs[NCmdArgs++] = CommandLine;
  965.     EchoArgs(CmdArgs, NCmdArgs);
  966.     Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  967.     if(!Options->Verbose)
  968.         {
  969.         unlink("wddjcc.cfg");
  970.         unlink("wddjcc.rsp");
  971.         }
  972.     if(Status)
  973.         exit(EXIT_FAILURE);
  974. LINK:
  975.     if(Options->LibName)
  976.         {
  977.         int     i;
  978.         char    Path[128];
  979.         NCmdArgs    = 1;
  980.         memset(CmdArgs, 0, MAX_ARGS * sizeof(char *));
  981.         CmdArgs[0]  = "tlib";
  982.         ResponseFile    = OpenFile("wddjlb.rsp", "w");
  983.         CmdArgs[NCmdArgs++] = Options->LibName;
  984.         CmdArgs[NCmdArgs++] = "/C"; /* case-sensitive library */
  985.         for(i = 0; i < FilesByExt[EXT_C].NFiles; ++i)
  986.             {
  987.             CopyPathName(FilesByExt[EXT_C].Array[i], Path);
  988.             fprintf(ResponseFile, "-+%s.obj ", Path);
  989.             }
  990.         for(i = 0; i < FilesByExt[EXT_CPP].NFiles; ++i)
  991.             {
  992.             CopyPathName(FilesByExt[EXT_CPP].Array[i], Path);
  993.             fprintf(ResponseFile, "-+%s.obj ", Path);
  994.             }
  995.         for(i = 0; i < FilesByExt[EXT_OBJ].NFiles; ++i)
  996.             {
  997.             CopyPathName(FilesByExt[EXT_OBJ].Array[i], Path);
  998.             fprintf(ResponseFile, "-+%s.obj ", Path);
  999.             }
  1000.         fclose(ResponseFile);
  1001.         CmdArgs[NCmdArgs++] = "@wddjlb.rsp";
  1002.         EchoArgs(CmdArgs, NCmdArgs);
  1003.         Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  1004.         if(!Options->Verbose)
  1005.             unlink("wddjlb.rsp");
  1006.         if(Status)
  1007.             exit(EXIT_FAILURE);
  1008.         }
  1009.     if(Options->CompileOnly)
  1010.         return;
  1011.     else
  1012.         {
  1013.         int     Status;
  1014.         int     i;
  1015.         char    Path[128];
  1016.  
  1017.         NCmdArgs    = 1;
  1018.         memset(CmdArgs, 0, MAX_ARGS * sizeof(char *));
  1019.         CmdArgs[0]  = "tlink";
  1020.         ResponseFile    = OpenFile("wddjln.rsp", "w");
  1021.         if(getenv("LIB"))
  1022.             fprintf(ResponseFile, " /L%s +\n", getenv("LIB"));
  1023.         CmdArgs[NCmdArgs++] = "/A=16";
  1024.         CmdArgs[NCmdArgs++] = "/c";
  1025.         if(Options->Debug > 0)
  1026.             CmdArgs[NCmdArgs++] = "/v";
  1027.         if(Options->MapFile)
  1028.             CmdArgs[NCmdArgs++] = "/l /s";
  1029.         else
  1030.             CmdArgs[NCmdArgs++] = "/x";
  1031.             
  1032.         if(Options->Com)
  1033.             CmdArgs[NCmdArgs++] = "/Tdc";
  1034.         else if(Options->Windows)
  1035.             {
  1036.             if(Options->Dll)
  1037.                 CmdArgs[NCmdArgs++] = "/Twd";
  1038.             else
  1039.                 CmdArgs[NCmdArgs++] = "/Twe";
  1040.             }
  1041.         else
  1042.             CmdArgs[NCmdArgs++] = "/Tde";
  1043.  
  1044.         fprintf(ResponseFile, "c0");
  1045.         if(Options->Windows)
  1046.             fprintf(ResponseFile, "%c", Options->Dll ? 'd' : 'w');
  1047.         fprintf(ResponseFile, "%c.obj", Options->MemoryModel);
  1048.         if(Options->WildCards)
  1049.             {
  1050.             char    Path[128];
  1051.             if(!SearchPath(getenv("LIB"), "wildargs.obj", Path))
  1052.                 fprintf(stderr, "Warning: Could not locate wildargs.obj\n");
  1053.             else
  1054.                 fprintf(ResponseFile, " + %s", Path);
  1055.             }
  1056.         for(i = 0; i < FilesByExt[EXT_C].NFiles; ++i)
  1057.             {
  1058.             CopyPathName(FilesByExt[EXT_C].Array[i], Path);
  1059.             fprintf(ResponseFile, " + %s.obj", Path);
  1060.             }
  1061.         for(i = 0; i < FilesByExt[EXT_CPP].NFiles; ++i)
  1062.             {
  1063.             CopyPathName(FilesByExt[EXT_CPP].Array[i], Path);
  1064.             fprintf(ResponseFile, " + %s.obj", Path);
  1065.             }
  1066.         for(i = 0; i < FilesByExt[EXT_OBJ].NFiles; ++i)
  1067.             {
  1068.             CopyPathName(FilesByExt[EXT_OBJ].Array[i], Path);
  1069.             fprintf(ResponseFile, " + %s.obj", Path);
  1070.             }
  1071.         fprintf(ResponseFile, ",+\n");
  1072.         fprintf(ResponseFile, "%s.%s", Options->RunName,
  1073.             Options->Com ? "com" : Options->Dll ? "dll" : "exe");
  1074.         fprintf(ResponseFile, ",+\n");
  1075.         fprintf(ResponseFile, ",+\n");
  1076.         if(Options->Windows)
  1077.             {
  1078.             for(i = 0; i < FilesByExt[EXT_LIB0].NFiles; ++i)
  1079.                 {
  1080.                 CopyPathName(FilesByExt[EXT_LIB0].Array[i], Path);
  1081.                 fprintf(ResponseFile, "%s.lib + ", Path);
  1082.                 }
  1083.             fprintf(ResponseFile, "cw%c.lib",
  1084.                 Options->MemoryModel);
  1085.             for(i = 0; i < FilesByExt[EXT_LIB1].NFiles; ++i)
  1086.                 {
  1087.                 CopyPathName(FilesByExt[EXT_LIB1].Array[i], Path);
  1088.                 fprintf(ResponseFile, " + %s.lib", Path);
  1089.                 }
  1090.             fprintf(ResponseFile, " + import");
  1091.             }
  1092.         else
  1093.             fprintf(ResponseFile, "c%c.lib",
  1094.                 Options->MemoryModel == 't' ? 's' : Options->MemoryModel);
  1095.         for(i = 0; i < FilesByExt[EXT_LIB].NFiles; ++i)
  1096.             {
  1097.             CopyPathName(FilesByExt[EXT_LIB].Array[i], Path);
  1098.             fprintf(ResponseFile, " + %s.lib", Path);
  1099.             }
  1100.         if(Options->Windows)
  1101.             {
  1102.             fprintf(ResponseFile, ",+\n");
  1103.             if(FilesByExt[EXT_DEF].NFiles)
  1104.                 fprintf(ResponseFile, "%s\n", FilesByExt[EXT_DEF].Array[0]);
  1105.             else
  1106.                 {
  1107.                 GenModDef(Options->RunName, Options->Dll);
  1108.                 fprintf(ResponseFile, "%s.def\n", Options->RunName);
  1109.                 }
  1110.             }
  1111.         fclose(ResponseFile);
  1112.         CmdArgs[NCmdArgs++] = "@wddjln.rsp";
  1113.         EchoArgs(CmdArgs, NCmdArgs);
  1114.         Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  1115.         if(!Options->Verbose)
  1116.             unlink("wddjln.rsp");
  1117.         if(Status)
  1118.             exit(EXIT_FAILURE);
  1119.         if(Options->Windows)
  1120.             CompileRc(Compiler, Options);
  1121.         }
  1122.     }
  1123.  
  1124. void    Ztc(enum COMPILER_TYPE Compiler, COMPILE_OPTIONS *Options)
  1125.     {
  1126.     static char    MOption[10];
  1127.     static char    WOption[10];
  1128.     int     Status;
  1129.     FILE    *ResponseFile;
  1130.  
  1131.     if(FilesByExt[EXT_C].NFiles == 0 && FilesByExt[EXT_CPP].NFiles == 0)
  1132.         goto    LINK;
  1133.     ResponseFile    = OpenFile("wddjcc.rsp", "w");
  1134.  
  1135.     CmdArgs[0] = ((Compiler == SC) ? "sc" : "ztc");
  1136.  
  1137.     CmdArgs[NCmdArgs++] = "-c";
  1138.     if(Options->Verbose)
  1139.         CmdArgs[NCmdArgs++] = "-v";
  1140.     if(Options->CPlusPlus)
  1141.         CmdArgs[NCmdArgs++] = "-cpp";
  1142.     if(Options->ProcessorType >= 1)
  1143.         {
  1144.         static
  1145.         char    POption[8];
  1146.         sprintf(POption, "-%d", Options->ProcessorType);
  1147.         CmdArgs[NCmdArgs++] = POption;
  1148.         }
  1149.     if(Options->Optimize)
  1150.         CmdArgs[NCmdArgs++] = "-o";
  1151.     {
  1152.     static  char    Align[4];
  1153.     sprintf(Align, "-a%d", Options->Align);
  1154.     CmdArgs[NCmdArgs++] = Align;
  1155.     }
  1156.     sprintf(MOption, "-m%c%s%s", Options->MemoryModel,
  1157.         Options->SsNeqDs ? "w" : "",
  1158.         (Options->Prologue == 'd') ? "u" : "");
  1159.     CmdArgs[NCmdArgs++] = MOption;
  1160.  
  1161.     if(Options->Windows)
  1162.         {
  1163.         if(Options->Prologue == 'a' || Options->Prologue == 'd')
  1164.             strcpy(WOption, "-W2");
  1165.         else if(Options->Prologue == 's')
  1166.             strcpy(WOption, "-W3");
  1167.         CmdArgs[NCmdArgs++] = WOption;
  1168.         }
  1169.     if(Options->Debug > 1)
  1170.         CmdArgs[NCmdArgs++] = "-g";
  1171.     else if(Options->Debug > 0)
  1172.         CmdArgs[NCmdArgs++] = "-gl";
  1173.     if(Options->CodeSegment && *Options->CodeSegment)
  1174.         {
  1175.         static char CodeSegment[64];
  1176.         sprintf(CodeSegment, "-NT%s", Options->CodeSegment);
  1177.         CmdArgs[NCmdArgs++] = CodeSegment;
  1178.         }
  1179.     if(Options->StackCheck)
  1180.         CmdArgs[NCmdArgs++] = "-s";
  1181.     {
  1182.     int     i;
  1183.     char    Path[128];
  1184.     for(i = 0; i < FilesByExt[EXT_C].NFiles; ++i)
  1185.         {
  1186.         CopyPathName(FilesByExt[EXT_C].Array[i], Path);
  1187.         fprintf(ResponseFile, " %s.c", Path);
  1188.         }
  1189.     for(i = 0; i < FilesByExt[EXT_CPP].NFiles; ++i)
  1190.         {
  1191.         CopyPathName(FilesByExt[EXT_CPP].Array[i], Path);
  1192.         fprintf(ResponseFile, " %s.cpp", Path);
  1193.         }
  1194.     }
  1195.     fclose(ResponseFile);
  1196.     CmdArgs[NCmdArgs++] = "@wddjcc.rsp";
  1197.     EchoArgs(CmdArgs, NCmdArgs);
  1198.     Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  1199.     if(!Options->Verbose)
  1200.         unlink("wddjcc.rsp");
  1201.     if(Status)
  1202.         exit(EXIT_FAILURE);
  1203.     if(Options->CompileOnly)
  1204.         return;
  1205.     else
  1206.         {
  1207.         char    *Plus = "";
  1208.         int     Status;
  1209.         int     i;
  1210.         char    Path[128];
  1211.  
  1212. LINK:
  1213.         NCmdArgs    = 1;
  1214.         memset(CmdArgs, 0, MAX_ARGS * sizeof(char *));
  1215.         CmdArgs[0]          = ((Compiler == SC) ? "link" : "blinkx");
  1216.         ResponseFile        = OpenFile("wddjln.rsp", "w");
  1217.         CmdArgs[NCmdArgs++] = "/nologo";
  1218.         if(Options->Debug > 0)
  1219.             CmdArgs[NCmdArgs++] = "/debug/codeview:4";
  1220.         if(Options->MapFile)
  1221.             CmdArgs[NCmdArgs++] = "/map";
  1222.         if(!Options->Windows)
  1223.             CmdArgs[NCmdArgs++] = "/dosseg";
  1224.         if(Options->Verbose)
  1225.             CmdArgs[NCmdArgs++] = "/information";
  1226.  
  1227.         Plus    = "";
  1228.         if(Options->MemoryModel == 't')
  1229.             fprintf(ResponseFile, "ct.obj"), Plus = " + ";
  1230.         for(i = 0; i < FilesByExt[EXT_C].NFiles; ++i)
  1231.             {
  1232.             CopyPathName(FilesByExt[EXT_C].Array[i], Path);
  1233.             fprintf(ResponseFile, "%s%s.obj", Plus, Path);
  1234.             Plus    = " + ";
  1235.             }
  1236.         for(i = 0; i < FilesByExt[EXT_CPP].NFiles; ++i)
  1237.             {
  1238.             CopyPathName(FilesByExt[EXT_CPP].Array[i], Path);
  1239.             fprintf(ResponseFile, "%s%s.obj", Plus, Path);
  1240.             Plus    = " + ";
  1241.             }
  1242.         if(Options->Com)
  1243.             {
  1244.             fprintf(ResponseFile, "%sct.obj", Plus);
  1245.             Plus    = " + ";
  1246.             }
  1247.         for(i = 0; i < FilesByExt[EXT_OBJ].NFiles; ++i)
  1248.             {
  1249.             CopyPathName(FilesByExt[EXT_OBJ].Array[i], Path);
  1250.             fprintf(ResponseFile, "%s%s.obj", Plus, Path);
  1251.             Plus    = " + ";
  1252.             }
  1253.         fprintf(ResponseFile, "\n");
  1254.         fprintf(ResponseFile, "%s.%s", Options->RunName,
  1255.             Options->Dll ? "dll" : "exe");
  1256.         fprintf(ResponseFile, "\n");
  1257.         fprintf(ResponseFile, "\n");
  1258.         Plus    = "";
  1259.         for(i = 0; i < FilesByExt[EXT_LIB].NFiles; ++i)
  1260.             {
  1261.             CopyPathName(FilesByExt[EXT_LIB].Array[i], Path);
  1262.             fprintf(ResponseFile, "%s%s.lib", Plus, Path);
  1263.             Plus    = " + ";
  1264.             }
  1265.         if(Options->Windows)
  1266.             {
  1267.             fprintf(ResponseFile, "\n");
  1268.             if(FilesByExt[EXT_DEF].NFiles)
  1269.                 fprintf(ResponseFile, "%s\n", FilesByExt[EXT_DEF].Array[0]);
  1270.             else
  1271.                 {
  1272.                 GenModDef(Options->RunName, Options->Dll);
  1273.                 fprintf(ResponseFile, "%s.def\n", Options->RunName);
  1274.                 }
  1275.             }
  1276.         fclose(ResponseFile);
  1277.         CmdArgs[NCmdArgs++] = "@wddjln.rsp";
  1278.         EchoArgs(CmdArgs, NCmdArgs);
  1279.         Status  = spawnvp(P_WAIT, CmdArgs[0], CmdArgs);
  1280.         if(!Options->Verbose)
  1281.             unlink("wddjln.rsp");
  1282.         if(Status)
  1283.             exit(EXIT_FAILURE);
  1284.         if(Options->Windows)
  1285.             CompileRc(Compiler, Options);
  1286.         if(Options->Com)
  1287.             {
  1288.             char    Path[128];
  1289.             NCmdArgs    = 1;
  1290.             memset(CmdArgs, 0, MAX_ARGS * sizeof(char *));
  1291.             CmdArgs[0]          = "exe2bin";
  1292.             sprintf(Path, "%s.exe %s.com", Options->RunName, Options->RunName);
  1293.             CmdArgs[NCmdArgs++] = Path;
  1294.             EchoArgs(CmdArgs, NCmdArgs);
  1295.             execvp(CmdArgs[0], CmdArgs);
  1296.             }
  1297.         }
  1298.     }
  1299.  
  1300.